package com.microframework.boot.system.controller;

import java.sql.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.microframework.base.core.datasource.annotation.Tx;
import com.microframework.base.core.security.constants.SecurityConstants;
import com.microframework.base.core.util.EncryptUtil;
import com.microframework.base.core.util.SecurityUtils;
import com.microframework.base.core.util.UuidUtil;
import com.microframework.base.web.page.PageQuery;
import com.microframework.base.web.resp.R;
import com.microframework.boot.system.model.domain.User;
import com.microframework.boot.system.model.domain.UserRole;
import com.microframework.boot.system.model.request.DelUsersReq;
import com.microframework.boot.system.model.request.UserPwdUpdateReqDTO;
import com.microframework.boot.system.model.response.SysRoute;
import com.microframework.boot.system.service.IMenuService;
import com.microframework.boot.system.service.IUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;

/**
 * 用户管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/sys/user")
@Tag(name = "用户管理", description = "用户管理相关接口")
public class UserController {

    @Autowired
    private IUserService userService;
    
    @Autowired
    private IMenuService menuService;
    
    
	@Operation(summary = "获取用户信息")
	@GetMapping("/info")
    public R<?> getUserLoginInfo(){
		return userService.queryUserLoginInfo(SecurityUtils.getUserId());
    }
	
	@Operation(summary = "获取用户拥有菜单")
	@GetMapping("/{scope}/menus")
	public R<List<SysRoute>> getLoginUserMenus(@PathVariable("scope") String scope) {
	    return R.ok(menuService.getUserRoutes(SecurityUtils.getUserId(),scope));
	}
	
	@Operation(summary = "获取用户拥有角色Id集合")
	@Parameters({ @Parameter(name = "id", description = "用户id", required = true) })
	@GetMapping("/{id}/roleIds")
	public R<List<String>> getUserByRoleIds(@PathVariable("id") String id) {
	    try {
	        List<UserRole> userRoles = UserRole.dao.find(
	            "select role_id from " + UserRole.TABLE_NAME + " where user_id = ?", 
	            id
	        );
	        List<String> roleIds = userRoles.stream()
	            .map(UserRole::getRoleId)
	            .collect(Collectors.toList());
	        return R.ok(roleIds);
	    } catch (Exception e) {
	        log.error("获取用户角色异常: {}", e.getMessage());
	        return R.fail("获取用户角色失败");
	    }
	}
	
    @PostMapping("/pages")
    @Operation(summary = "分页查询用户列表", description = "分页查询登录日志数据")
    public R<Page<User>> pages(@RequestBody PageQuery<User> pageQuery) {
        return R.ok(userService.pages(pageQuery));
    }
	
	@Operation(summary = "保存用户")
	@Parameters({ @Parameter(name = "user", description = "用户", required = true) })
	@PostMapping("/save")
	@Tx
	public R<User> save(HttpServletRequest request, @RequestBody User user) {
		try {
			if (StrKit.notBlank(user.getId())) {
				User checkUser=User.dao.findFirst("select id from "+User.TABLE_NAME+" where username=? and id!=?",user.getUsername(),user.getId());
				if(checkUser!=null) {
					return R.fail("用户名重复！");
				}
				user.setModifyTime(new Date(System.currentTimeMillis()));
				user.setModifyUserId(SecurityUtils.getUserId());
				if (user.update()) {
					if (user.getRoles()!=null) {
						List<String> sqlList = new LinkedList<String>();
						StringBuffer sb = new StringBuffer();
						for(String roleId : user.getRoles()) {
							UserRole userRole = UserRole.dao.findByIds(user.getId(), roleId);
							if (userRole == null) {
								sqlList.add("insert " + UserRole.TABLE_NAME + " (user_id,role_id) VALUES('"
										+ user.getId() + "','" + roleId + "')");
							}
							sb.append("'").append(roleId).append("',");
						}
						if (!StrKit.isBlank(sb.toString())) {
							sqlList.add("delete from " + UserRole.TABLE_NAME + " where user_id='" + user.getId()
									+ "' and role_id not in(" + sb.toString().substring(0, sb.length() - 1) + ") ");
						}
						Db.batch(sqlList, sqlList.size());
					} else {
						Db.delete("delete from " + UserRole.TABLE_NAME + " where user_id=?", user.getId());
					}
					return R.ok(user);
				} else {
					return R.fail("更新失败！");
				}
			} else {
				User checkUser=User.dao.findFirst("select id from "+User.TABLE_NAME+" where username=? ",user.getUsername());
				if(checkUser!=null) {
					return R.fail("用户名重复！");
				}
				user.setId(UuidUtil.getUUID());
				user.setPassword(EncryptUtil.encryptPassword("rs@123"));
				user.setCreateTime(new Date(System.currentTimeMillis()));
				user.setCreateUserId(SecurityUtils.getUserId());
				
				if (user.save()) {
					if (user.getRoles()!=null) {
						List<String> sqlList = new LinkedList<String>();
						StringBuffer sb = new StringBuffer();
						for(String roleId : user.getRoles()) {
							UserRole userRole = UserRole.dao.findByIds(user.getId(), roleId);
							if (userRole == null) {
								sqlList.add("insert " + UserRole.TABLE_NAME + " (user_id,role_id) VALUES('"
										+ user.getId() + "','" + roleId + "')");
							}
							sb.append("'").append(roleId).append("',");
						}
						if (!StrKit.isBlank(sb.toString())) {
							sqlList.add("delete from " + UserRole.TABLE_NAME + " where user_id='" + user.getId()
									+ "' and role_id not in(" + sb.toString().substring(0, sb.length() - 1) + ") ");
						}
						Db.batch(sqlList, sqlList.size());
					} else {
						Db.delete("delete from " + UserRole.TABLE_NAME + " where user_id=?", user.getId());
					}
					return R.ok(user);
				} else {
					return R.fail("保存失败.");
				}
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "删除用户")
	@Parameters({ @Parameter(name = "id", description = "用户id", required = true) })
	@DeleteMapping("/detain/{id}")
	public R<String> deleteUserById(@PathVariable("id") String id) {
		try {
			User user=new User();
			user.setId(id);
			user.setIsDel("1");
			user.setStatus("-1");
			if(user.update()) {
				return R.ok("删除成功.");
			}else {
				return R.fail("删除失败.");
			}
		}catch (Exception e) {
			log.error("删除用户异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "批量删除用户")
	@Parameters({ @Parameter(name = "delUsersReq", description = "需要删除的用户Id集合", required = true) })
	@RequestMapping(value = "/del/users", method = RequestMethod.POST)
	@Tx 
	public R<String> delUsers(@RequestBody DelUsersReq delUsersReq) {
	    // 1. 参数校验
	    if (delUsersReq == null || delUsersReq.getIds() == null || delUsersReq.getIds().isEmpty()) {
	        return R.fail("待删除的用户ID列表不能为空");
	    }
	    try {
	        // 2. 使用 JFinal 的批量更新（避免循环单条更新）
//	        Db.tx(() -> {
//	            String sql = "UPDATE "+User.TABLE_NAME+" SET is_del = '1', status = '-1' WHERE id = ?";
//	            Object[][] params = new Object[delUsersReq.getIds().size()][1];
//	            for (int i = 0; i < delUsersReq.getIds().size(); i++) {
//	                params[i][0] = delUsersReq.getIds().get(i);
//	            }
//	            Db.batch(sql, params, 100); // 每批100条执行
//	            return true;
//	        });
	    	
            String sql = "UPDATE "+User.TABLE_NAME+" SET is_del = '1', status = '-1' WHERE id = ?";
            Object[][] params = new Object[delUsersReq.getIds().size()][1];
            for (int i = 0; i < delUsersReq.getIds().size(); i++) {
                params[i][0] = delUsersReq.getIds().get(i);
            }
            Db.use(User.DS_NAME).batch(sql, params, 100); // 每批100条执行
	        log.info("批量删除用户成功，影响用户数: {}", delUsersReq.getIds().size());
	        return R.ok("成功删除 " + delUsersReq.getIds().size() + " 个用户");
	    } catch (Exception e) {
	        log.error("批量删除用户失败，用户ID: {}, 错误原因: {}", delUsersReq.getIds(), e.getMessage(), e);
	        return R.fail("删除失败，请稍后重试");
	    }
	}
	
	@Operation(summary = "重置用户密码")
	@Parameters({ @Parameter(name = "user", description = "用户(只需带Id)", required = true) })
	@RequestMapping(value = "/pwd/reset", method = RequestMethod.POST)
	public R<String> resetPwd() {
		try {
			User user=new User();
			user.setId(SecurityUtils.getUserId());
			user.setPassword(EncryptUtil.encryptPassword("rs@123"));
			if (user.update()) {
				return R.ok("重置成功.");
			}
			return R.fail("重置失败.");
		}catch (Exception e) {
			log.error("重置用户密码异常:{}",e.getMessage());
			return R.fail(e.getMessage());
		}
	}
	
	@Operation(summary = "修改用户密码")
	@Parameters({ @Parameter(name = "userpassword", description = "用户密码", required = true) })
	@RequestMapping(value = "/pwd/update", method = RequestMethod.POST)
	public R<User> password(@RequestBody UserPwdUpdateReqDTO userpassword) {
		try {
			if (userpassword == null || StrKit.isBlank(userpassword.getOldPassword())
					|| StrKit.isBlank(userpassword.getNewPassword())) {
				return R.fail("参数必填.");
			}
			String oldPwd = "";
			String newPwd = "";
			try {
				oldPwd = EncryptUtil.rsaDecrypt(userpassword.getOldPassword(), SecurityConstants.PRIVATE_KEY);
				newPwd = EncryptUtil.rsaDecrypt(userpassword.getNewPassword(), SecurityConstants.PRIVATE_KEY);
			} catch (Exception e) {
				e.printStackTrace();
				return R.fail("解密信息失败!");
			}

			User user = User.dao.findById(SecurityUtils.getUserId());
			if (user == null) {
				return R.fail("用户不存在.");
			}

			if (!EncryptUtil.verifyPassword(oldPwd, user.getPassword())) {
				return R.fail("原始密码错误.");
			}
			user.setPassword(EncryptUtil.encryptPassword(newPwd));
			if (user.update()) {
				return R.ok();
			} else {
				return R.fail("失败.");
			}
		} catch (Exception e) {
			return R.fail(e.getMessage());
		}
	}
	
//	@Operation(summary = "根据id查询用户信息")
//	@Parameters({ @Parameter(name = "id", description = "用户Id", required = true)})
//	@GetMapping(value = { "/detail/info/{id}" }, produces = "application/json; charset=utf-8")
//    public R<?> queryUserById(@PathVariable("id") String id){
//		return userService.queryUserById(id);
//    }
    
} 